# -*- coding: utf-8 -*-
"""
与建立class相关的魔术方法
"""
from common import trace


class Base:
    @trace
    def __init_subclass__(cls, name, **kwargs):
        print(cls)
        print(kwargs)
        cls.x = {}
        cls.name = name
        super().__init_subclass__(**kwargs)


class D:
    @trace
    def __set_name__(self, owner, name):
        print(self, owner, name)
        self.name = name


class A(Base, name='Jack'):
    x = D()

    @trace
    def __class_getitem__(cls, item):
        print(cls, item)
        return 'abc'


class X:
    @trace
    def __mro_entries__(self, bases):
        """找基类 tuple"""
        print(self, bases)
        return (X,)


class Y(X()):
    pass


class MyGenericClass:
    @classmethod
    def __class_getitem__(cls, item):
        return f"MyGenericClass[{item.__name__}]"


class MyTypeHintedClass:
    MyList = MyGenericClass[int]


class MyGenericClass2:
    @classmethod
    def __class_getitem__(cls, item):
        return f"MyGenericClass2[{str(item)}]"


class Meta(type):
    @classmethod
    @trace
    def __prepare__(metacls, name, bases, **kwargs):
        print('__prepare__', metacls, name, bases, kwargs)
        return kwargs


class MyCls(metaclass=Meta):
    pass


if __name__ == '__main__':
    a = A()
    print(a.x, A.x, A.name)

    print(A['name'])
    print(A['x'], A.x)

    # list的　type hint 就是通过 __class_getitem__ 实现的
    int_arr_type = list[int]
    list1: int_arr_type = [1]
    list2: int_arr_type = ['a']

    # 使用类型提示
    value: MyTypeHintedClass.MyList = [1, 2, 3]
    my_list: MyGenericClass2[int] = [1, 2, 3]
    my_dict: MyGenericClass2[str, int] = {'a': 1, 'b': 2}

    y = Y()
    print(issubclass(Y, X))


    print(MyCls)